package com.metadata_system.common.dto;

import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import com.metadata_system.common.utils.MyUtil;
import com.metadata_system.common.utils.RegexUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Slf4j
public class MyField {
    // 字段名称
    String name;
    // 字段key
    String field;
    // 字段格式描述
    String des;
    // 字段内容类型: 1.username(0~9A~Za~z_-)   2.name(中文/0~9A~Za~z_-) 3.password  4.enums 5.money(>0)
    String type;
    // 长度
    List<Integer> length;
    // 长度
    List enums;
    // 是否可选
    Boolean isRequire;

    public MyField(String name, String field, String des, String type, List<Integer> length, boolean isRequire) {
        this.name = name;
        this.field = field;
        this.des = des;
        this.type = type;
        this.length = length;
        this.isRequire = isRequire;
    }

    public static ApiResult checkValue(String type,String value){
        if (type.equals("image")){
            if (value.equals("")){
                return ApiResult.success();
            }
            if (!RegexUtils.checkImageUrl(value)){
                return ApiResult.error("地址错误");
            }else{
                return ApiResult.success();
            }
        }
        if (type.equals("date")){
            if (!RegexUtils.checkBirthday(value)){
                return ApiResult.error("日期错误");
            }else{
                return ApiResult.success("日期正确");
            }
        }
        return ApiResult.error("类型不存在");
    }


    /**
     * 规则检查
     * @param list  字段列表
     * @param dataParams   数据map
     * @param isCreate  是否为创建操作
     * @return
     */
    public static ApiResult checkRule(List<MyField> list, Object dataParams,boolean isCreate){
        Map dataMap = JSON.parseObject(JSON.toJSONString(dataParams), Map.class);
        for (MyField myField : list) {
            // 1.更新操作,且没传值(非创建 && 数据为null)
            Object objectValue = dataMap.get(myField.getField());
            if ((!isCreate || !myField.isRequire) && objectValue==null){
                // 空值 && (更新,非必选)  可跳过
                continue;
            }
            if (isCreate && myField.isRequire && objectValue==null){
                if (myField.getLength().get(0)>0){
                    return ApiResult.error(myField.getName()+" 不能为空");
                }
            }
            String value=dataMap.get(myField.getField()).toString();
            Integer length=value.length();

            // 2.长度判断
            if (myField.getLength()!=null && !myField.getType().equals("integer")){
                if (length<myField.getLength().get(0) || length>myField.getLength().get(1)){
                    return ApiResult.error(myField.getName()+" 长度必须在"+myField.getLength().get(0)+","+myField.getLength().get(1)+"之间");
                }
            }

            // 3.特殊字段类型判断
            switch (myField.getType()){
                // 用户名-类型
                case "username":
                    if (!RegexUtils.check("username",value)){
                        return ApiResult.error(myField.getName()+" "+myField.getDes());
                    }
                    break;
                // 姓名-类型
                case "name":
                case "text":
                    if (MyUtil.isAllBlank(value) && myField.getLength().get(0)>0){
                        return ApiResult.error(myField.getName()+" 不能全部位空字符串");
                    }
                    break;
                // 整型
                case "integer":
                    try {
                        int i = Integer.parseInt(value);
                        if (i<myField.getLength().get(0) || i>myField.getLength().get(1)){
                            return ApiResult.error(myField.getName()+" 必须在"+myField.getLength().get(0)+","+myField.getLength().get(1)+"之间");
                        }
                    }catch (Exception e){
                        return ApiResult.error("数值必须为整型");
                    }
                    break;
                // 金额-类型
                case "decimals":
                    BigDecimal bigDecimal=BigDecimal.ZERO;
                    try {
                        bigDecimal = BigDecimal.valueOf(Double.parseDouble(value));
                    }catch (Exception e){
                        return ApiResult.error("格式必须不符合金额格式");
                    }
                    if (bigDecimal.compareTo(BigDecimal.ZERO)<0){
                        return ApiResult.error(myField.getName()+" "+myField.getDes());
                    }
                    break;
                // 金额-类型
                case "jsonArr":
                    try {
                        List<Object> objects = JSON.parseArray(value, Object.class);
                    }catch (Exception e){
                        return ApiResult.error("必须符合 json数组格式 字符串");
                    }
                    break;
                // 地址-类型
                case "image":
                    if (!RegexUtils.check("imageUrl",value)){
                        return ApiResult.error(myField.getName()+" "+myField.getDes());
                    }
                    if (value.length()<20 || value.length()>200){
                        return ApiResult.error("图片格式长度错误,必须在(20,200)之间");
                    }
                    break;
                // 多地址-类型
                case "imageArr":
                    if (StringUtils.isBlank(value)){
                        break;
                    }
                    List<String> urlList = Arrays.asList(value.split(","));
                    for (String _url : urlList) {
                        if (!RegexUtils.check("imageUrl",_url)){
                            return ApiResult.error(myField.getName()+" "+myField.getDes()+"___"+_url);
                        }
                    }
                    break;
                // 手机号码-类型
                case "mobile":
                    if (!RegexUtils.check("mobile",value)){
                        return ApiResult.error(myField.getName()+"-"+myField.getDes());
                    }
                    break;
                // 日期-类型
                case "date":
                    if (!RegexUtils.check("birthday",value)){
                        return ApiResult.error(myField.getName()+"-"+myField.getDes());
                    }
                    break;
                // 时间段-类型
                case "timeArr":
                    String[] valueArr0 = value.split(",");
                    if (valueArr0.length!=2){
                        return ApiResult.error(myField.getName()+"-时间段 格式长度错误");
                    }
                    Integer startTime=Integer.valueOf(valueArr0[0].replace(":",""));
                    Integer endTime=Integer.valueOf(valueArr0[1].replace(":",""));
                    if (startTime<0 || startTime>2400){
                        return ApiResult.error(myField.getName()+"-开始时间 错误");
                    }
                    if (endTime<0 || endTime>2400){
                        return ApiResult.error(myField.getName()+"-结束时间 错误");
                    }
                    if (startTime>=endTime){
                        return ApiResult.error(myField.getName()+"-开始时间,结束时间不匹配");
                    }
                    break;
                // 定位信息
                case "location":
                    String[] valueArr1 = value.split(",");
                    if (valueArr1.length!=2){
                        return ApiResult.error(myField.getName()+"-定位信息错误");
                    }
                    Double lon=Double.parseDouble(valueArr1[0]);
                    Double lat=Double.parseDouble(valueArr1[1]);
                    if (lon<72 || lon>137){
                        return ApiResult.error(myField.getName()+"-定位信息[经度] 错误");
                    }
                    if (lat<2 || lat>56){
                        return ApiResult.error(myField.getName()+"-定位信息[维度] 错误");
                    }
                    break;
                // 枚举-类型
                case "enums":
                    if (!myField.getEnums().contains(value)){
                        return ApiResult.error(myField.getName()+"-取值范围错误 ["+value+"],必须在: ["+StringUtils.join(myField.getEnums().toArray(),",")+"]之中");
                    }
                    break;
            }
        }
        return ApiResult.success();
    }

//    public static void main(String[] args) {
//        ApiResult date = checkValue("date", "1908-22-11");
//        System.out.println(date.getCode());
//        System.out.println(date.getData().toString());
//    }


    /**
     * 根据字符串获取某服务定义字段规则
     * @param fieldString
     * @param serviceFieldList
     * @return
     */
    public static List<MyField> getField(String fieldString,List<MyField> serviceFieldList){
        List<MyField> tmpList = new ArrayList<>();
        List<String> fieldList = Arrays.asList(fieldString.split(","));
        for (String field : fieldList) {
            for (MyField myField : serviceFieldList) {
                if (field.equals(myField.getField())){
                    tmpList.add(myField);
                }
            }
        }
        return tmpList;
    }
}
